#include "../inc/balle.h"
#include <SDL/SDL.h>

#define FRICTION 0.9f
#define MASSE 3.f
#define MASSE_BLOB 8.f

Balle::Balle() {}

Balle::Balle(const vec2D c, const float r)
{
	centre = c;
	rayon = r;
	//~ direction.x = 0.5;
	//~ direction.y = 1;
	direction.x = 0.f;
	direction.y = 0.f;

	vitesse.x = 0.f; // ((float)(rand()%100) - 100.0f);
	vitesse.y = 0.f; // ((float)(rand()%100) - 100.0f);

	accel.x = 0.f;
	accel.y = 0.f;

	masse = MASSE;
}

void Balle::init(const vec2D c, const float r)
{
	centre = c;
	rayon = r;
	direction.x = 0.5;
	direction.y = 1;

	vitesse.x = 0.f; // ((float)(rand()%100) - 100.0f);
	vitesse.y = 0.f; // ((float)(rand()%100) - 100.0f);

	accel.x = 0.f;
	accel.y = 0.f;

	masse = MASSE;
}

void Balle::copy(Balle & b)
{
	centre = b.centre;
	rayon = b.rayon;
	direction = b.direction;
	masse = b.masse;
	vitesse = b.vitesse;
	accel = b.accel;
}

vec2D& Balle::getCentre()
{
	return centre;
}

float Balle::getRayon()
{
	return rayon;
}

vec2D Balle::getDirection()
{
	return direction;
}

vec2D Balle::getVitesse()
{
	return vitesse;
}

void Balle::setCentre(const vec2D &c)
{
	centre = c;
}

void Balle::setDirection(const vec2D &d)
{
	direction = d;
}

void Balle::setVitesse(const vec2D &v)
{
	vitesse = v;
}

void Balle::changeDirection(const vec2D normal)
{
	vec2D v(0,0);
	v.x = -direction.x;
	v.y = -direction.y;

	float val = v.dot(normal);
	//~ std::cout << v.x << " " << v.y << std::endl;

	v.x = val * normal.x;
	v.y = val * normal.y;
	//std::cout<<v.x<<" ____ "<<v.y<<std::endl;

	//~ v.x *= 2;
	//~ v.y *= 2;
	v.x *= 2.5;
	v.y *= 2.5;

	float lim = 200.f;

	//~ if (v.x > lim)
		//~ v.x = lim;
//~
	//~ if (v.y > lim)
		//~ v.y = lim;


	v.x += direction.x;
	v.y += direction.y;

	//~ v.normalize();

	std::cout<<v.x<<"  "<<v.y<<std::endl;

	//~ direction.x = v.x * 1.1;
	//~ direction.y = v.y * 1.1;
	direction.x = v.x;
	direction.y = v.y;

	if (direction.x > lim)
		direction.x = lim;
	if (direction.y > lim)
		direction.y = lim;
	if (direction.x < -lim)
		direction.x = -lim;
	if (direction.y < -lim)
		direction.y = -lim;

}

float Balle::radToDeg(const float angle)
{
	return 180 * (angle) / M_PI;
}

void Balle::ajouteForce(vec2D force)
{
	force.scale(1.f / masse);
	accel.add(force, 0.f);
}

void Balle::update(const float delta)
{
	//~ vitesse.add(accel, delta);
	//~ accel.scale(0.f);
	//~ centre.x += vitesse.x * delta;
	//~ centre.y += vitesse.y * delta;
	direction.add(accel, delta);
	accel.scale(0.5f);
	centre.x += direction.x * delta;
	centre.y += direction.y * delta;
}

void Balle::rebond()
{
	//~ std::cerr << SDL_GetVideoSurface()->w << " " << SDL_GetVideoSurface()->h << std::endl;
	//~ std::cerr << "Centre : " << centre.x << " " << centre.y << std::endl;
	//~ std::cerr << "Rayon : " << rayon << std::endl;

	vec2D fric;
	fric.x = FRICTION * masse;
	fric.y = FRICTION * masse;

	bool hitX = false;
	bool hitY = false;

	// Si touche le mur à gauche
	if (centre.x < rayon)
	{
		centre.x = rayon;
		direction.x *= -1.f;

		hitX = true;
	}

	// Si touche le "plafond"
	if (centre.y < rayon)
	{
		centre.y = rayon;
		direction.y *= -1.f;

		hitY = true;
	}

	// Si touche le mur à droite
	if (centre.x > SDL_GetVideoSurface()->w - rayon)
	{
		centre.x = (float)SDL_GetVideoSurface()->w - rayon;
		direction.x *= -1.f;

		hitX = true;
	}

	// Si touche le sol
	if (centre.y > SDL_GetVideoSurface()->h - rayon)
	{
		centre.y = (float)SDL_GetVideoSurface()->h - rayon;
		direction.y *= -1.f;

		hitY = true;
	}

	// En cas de collision
	if (hitX || hitY)
	{
		// Applique l'effet des frottements
		if (direction.x < 0.0f)
			direction.x += fric.x;
		else
			direction.x -= fric.x;

		if (direction.y < 0.0f)
			direction.y += fric.y;
		else
			direction.y -= fric.y;
	}
}

void Balle::renvoiBlob(Blob & b)
{
	vec2D fric;
	fric.x = FRICTION * masse;
	fric.y = FRICTION * masse;

	// Distance entre la balle et le blob (basee sur les centres)
	vec2D dist;
	dist.x = centre.x - b.getCentre().x;
	dist.y = centre.y - b.getCentre().y;

	// Le blob est considere comme une boule
	// Pythagore sur le triangle rectangle ABC -> respectivement (centre balle, centre blob, intersection dist.x-dist.y)
	if ( (dist.x * dist.x + dist.y * dist.y) < ((rayon + b.getLargeur() * 0.66) * (rayon + b.getLargeur() * 0.66)) )
	{
		// Collision
		dist.normalize();
		dist.x *= rayon + b.getLargeur() * 0.66;
		dist.y *= rayon + b.getLargeur() * 0.66;

		// Repositionnement
		centre.x = b.getCentre().x + dist.x;
		centre.y = b.getCentre().y + dist.y;

		// Garde la direction actuelle
		vec2D oldDir;
		oldDir.x = direction.x;
		oldDir.y = direction.y;

		// Nouvelle direction
		direction.x = (direction.x * (masse - MASSE_BLOB) + 2 * (MASSE_BLOB * 0.f)) / (masse + MASSE_BLOB);
		//~ direction.x *= -1.f;
		direction.y = (direction.y * (masse - MASSE_BLOB) + 2 * (MASSE_BLOB * -1.f)) / (masse + MASSE_BLOB);
		//~ direction.y *= -1.f;

		if (direction.x < 0.0f)
			direction.x += fric.x;
		else
			direction.x -= fric.x;

		if (direction.y < 0.0f)
			direction.y += fric.y;
		else
			direction.y -= fric.y;

	  //~ other->velocity.x = (other->velocity.x * (other->mass - mass) + 2 * (mass * velocityB.x)) / (mass + other->mass);
	  //~ other->velocity.y = (other->velocity.y * (other->mass - mass) + 2 * (mass * velocityB.y)) / (mass + other->mass);
//~
	  //~ //Add friction!
	  //~ if (other->velocity.x < 0.0f)
		 //~ other->velocity.x += FRICTION * other->mass;
	  //~ else
		 //~ other->velocity.x -= FRICTION * other->mass;
//~
	  //~ if (other->velocity.y < 0.0f)
		 //~ other->velocity.y += FRICTION * other->mass;
	  //~ else
		 //~ other->velocity.y -= FRICTION * other->mass;
   }
}
